package sb.simple.aspectj.annotation;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;

import java.lang.reflect.Method;
import java.util.Arrays;

@Configuration
@Aspect
public class AJAnnotation {

    /**注解于类@within*/
    @Pointcut("@within(sb.simple.aspectj.annotation.Require)&&execution(public * *.*(..))")
    public void pointClass() { }

    @Around("pointClass()")
    public Object aroundClass(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("aroundClass() in");

        //获取在类上的注解中的属性值
        String className = joinPoint.getTarget().getClass().getName();
        Class<?> clz = Class.forName(className);
        Require require = clz.getAnnotation(Require.class);
        System.out.println("annotation(class), clzName:" + clz.getSimpleName());
        String value = require.value();
        System.out.println("annotation(class)->Require->value:" + value);

        return joinPoint.proceed();
    }


    /**注解于方法@annotation*/
    @Pointcut("@annotation(sb.simple.aspectj.annotation.Require)")
    public void point() { }


    @Around("point()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("aroundMethod() in");

        //获取在方法上的注解的属性值
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Class<?> clz = joinPoint.getTarget().getClass();
        String name = signature.getName();
        Class[] parameterTypes = signature.getParameterTypes();
        Method method = clz.getMethod(name, parameterTypes);
        System.out.println("annotation(method), clzName:" + clz.getSimpleName() + ", name:" + name + ", parameterTypes:" + Arrays.toString(parameterTypes));
        Require require = method.getAnnotation(Require.class);
        String value = require.value();
        System.out.println("annotation(method)->Require->value:" + value);


        return joinPoint.proceed();
    }
}
